package com.ruoyi.recycle.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.recycle.domain.MerchantManagement;
import com.ruoyi.recycle.exception.BusinessException;
import com.ruoyi.recycle.mapper.MerchantManagementMapper;
import com.ruoyi.recycle.properties.Wxproperties;
import com.ruoyi.recycle.service.IMerchantManagementService;
import com.ruoyi.recycle.utils.MiniProgramUtil;
import com.ruoyi.system.api.RemoteLoginService;
import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.form.LoginBody;
import com.ruoyi.system.api.model.LoginUser;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 综合站管理Service业务层处理
 *
 * @author Wubk
 * @date 2022-05-21
 */
@Service
@Slf4j
public class MerchantManagementServiceImpl extends ServiceImpl<MerchantManagementMapper, MerchantManagement> implements IMerchantManagementService {
    @Autowired
    private MerchantManagementMapper merchantManagementMapper;
    @Autowired
    private RemoteLoginService remoteLoginService;
    @Autowired
    private RemoteUserService remoteUserService;
    @Autowired
    private Wxproperties wxproperties;
    private static Map<String, Long> roleMap = new HashMap<>(2);

    static {
        roleMap.put("订单管理", 3L);
        roleMap.put("财务管理", 4L);
    }


    /**
     * 查询综合站管理
     *
     * @param id 综合站管理主键
     * @return 综合站管理
     */
    @Override
    public MerchantManagement selectMerchantManagementById(Long id) {
        return merchantManagementMapper.selectMerchantManagementById(id);
    }

    /**
     * 查询综合站管理列表
     *
     * @param merchantManagement 综合站管理
     * @return 综合站管理
     */
    @Override
    public List<MerchantManagement> selectMerchantManagementList(MerchantManagement merchantManagement) {
        return merchantManagementMapper.selectMerchantManagementList(merchantManagement);
    }

    /**
     * 新增综合站管理
     *
     * @param merchantManagement 综合站管理
     * @return 结果
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public int insertMerchantManagement(MerchantManagement merchantManagement) {
        final MerchantManagement exist = getOne(Wrappers.query(new MerchantManagement().setMerchantNumber(merchantManagement.getMerchantNumber())));
        if (Objects.nonNull(exist)) {
            throw new BusinessException("添加的账号已存在,请重新输入");
        }
        final R<?> register = remoteLoginService.register(new LoginBody()
                .setUsername(merchantManagement.getMerchantNumber())
                .setPassword(merchantManagement.getMerchantPassword()));
        if (StrUtil.isNotEmpty(register.getMsg())) {
            throw new BusinessException(register.getMsg());
        }
        final R<LoginUser> userInfo = remoteUserService.getUserInfo(merchantManagement.getMerchantNumber(), SecurityConstants.INNER);
        final Long userId = userInfo.getData().getSysUser().getUserId();
        merchantManagement.setUserId(userId);
        AjaxResult ajaxResult = new AjaxResult();
        if (merchantManagement.getParentId() == null) {
            ajaxResult = remoteUserService.insertAuthRole(userId, ArrayUtil.wrap(3L, 4L), SecurityConstants.INNER);

        } else {
            final List<String> roleNames = merchantManagement.getRoleNames();
            if (CollUtil.isNotEmpty(roleNames)) {
                List<Long> roleIds = new ArrayList<>();
                roleNames.forEach(rn -> roleIds.add(roleMap.get(rn)));
                final Long[] array = roleIds.toArray(new Long[roleIds.size()]);
                ajaxResult = remoteUserService.insertAuthRole(userId, array, SecurityConstants.INNER);

            }
        }
        if ((Integer) ajaxResult.get("code") != 200) {
            throw new BusinessException((String) ajaxResult.get("msg"));
        }
        if (StrUtil.isEmpty(merchantManagement.getPortrait())) {
            merchantManagement.setPortrait(wxproperties.getDefaultPortraitC());
        }
        return saveOrUpdate(merchantManagement.setStatus("1")) ? 1 : 0;
    }

    /**
     * 修改综合站管理
     *
     * @param merchantManagement 综合站管理
     * @return 结果
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public int updateMerchantManagement(MerchantManagement merchantManagement) {
        final String password = merchantManagement.getPassword();
        if (StrUtil.isNotEmpty(password)) {
            final SysUser sysUser = new SysUser();
            sysUser.setUserName(merchantManagement.getMerchantNumber());
            sysUser.setPassword(merchantManagement.getPassword());
            sysUser.setUserId(merchantManagement.getUserId());
            final AjaxResult ajaxResult = remoteUserService.resetPwd(sysUser, SecurityConstants.INNER);
            if (StrUtil.equals((String) ajaxResult.get("code"), "500")) {
                throw new BusinessException("重置密码失败");
            }
        }
        final R<LoginUser> userInfo = remoteUserService.getUserInfo(merchantManagement.getMerchantNumber(), SecurityConstants.INNER);
        final List<String> roleNames = merchantManagement.getRoleNames();
        final Long userId = userInfo.getData().getSysUser().getUserId();
        AjaxResult ajaxResult = new AjaxResult();
        if (CollUtil.isNotEmpty(roleNames)) {
            if (merchantManagement.getParentId() == null) {
                ajaxResult = remoteUserService.insertAuthRole(userId, ArrayUtil.wrap(3L, 4L), SecurityConstants.INNER);
            } else {
                List<Long> roleIds = new ArrayList<>();
                roleNames.forEach(rn -> roleIds.add(roleMap.get(rn)));
                final Long[] array = roleIds.toArray(new Long[roleIds.size()]);
                ajaxResult = remoteUserService.insertAuthRole(userId, array, SecurityConstants.INNER);

            }
            if ((Integer) ajaxResult.get("code") != 200) {
                throw new BusinessException(StrUtil.format("修改角色权限失败,原因:{}", ajaxResult.get("msg")));
            }

        }
        return merchantManagementMapper.updateById(merchantManagement);
    }

    /**
     * 批量删除综合站管理
     *
     * @param ids 需要删除的综合站管理主键
     * @return 结果
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public int deleteMerchantManagementByIds(Long[] ids) {
        final List<MerchantManagement> managements = list(Wrappers.lambdaQuery(new MerchantManagement())
                .in(MerchantManagement::getId, ids));
        remoteUserService.remove(managements.stream().map(MerchantManagement::getUserId).toArray(Long[]::new), SecurityConstants.INNER);
        return merchantManagementMapper.deleteMerchantManagementByIds(ids);
    }

    /**
     * 删除综合站管理信息
     *
     * @param id 综合站管理主键
     * @return 结果
     */
    @Override
    public int deleteMerchantManagementById(Long id) {
        return merchantManagementMapper.deleteMerchantManagementById(id);
    }


    @Override
    public int changeStatus(Long id, String status) {
        return merchantManagementMapper.updateMerchantManagement(new MerchantManagement().setStatus(status).setId(id));
    }

    @Override
    public AjaxResult saveIntegral(Long id, Long integral) {

        MerchantManagement merchantManagement = merchantManagementMapper.selectMerchantManagementById(id);

        merchantManagement.setIntegral(merchantManagement.getIntegral() == null ? integral : merchantManagement.getIntegral() + integral);
        merchantManagementMapper.updateById(merchantManagement);

        return AjaxResult.success();
    }

    /**
     * 生成小程序码
     * todo 未完成，需要和前段确认好，生成综合站小程序码需要哪些内容，基本基地没问题
     *
     * @param id
     * @return
     */
    @Override
    public AjaxResult getMiniProgram(Long id) {
        MerchantManagement merchantManagement = merchantManagementMapper.selectMerchantManagementById(id);

        if (merchantManagement.getMiniProgramCode() == null) {
            String miniqrQr = MiniProgramUtil.postMiniqrQr(merchantManagement.getOpenid(), "pages/index/index", MiniProgramUtil.getToken("wxc1c3b06bb75f14ba","f75025b2e55941f579ef625e1dc4886f"));
            merchantManagement.setMiniProgramCode(miniqrQr);
            merchantManagementMapper.updateById(merchantManagement);
        }
        return AjaxResult.success().put("miniProgram", merchantManagement.getMiniProgramCode());


    }


    @Override
    public AjaxResult nearbyMerchantRecommend(Double dis, Double longitude, Double latitude) {
        //先计算查询点的经纬度范围
        List<MerchantManagement>  tshoplist = null;
        try {
            double r = 6371;//地球半径千米
            double dlng =  2*Math.asin(Math.sin(dis/(2*r))/Math.cos(latitude*Math.PI/180));
            dlng = dlng*180/Math.PI;//角度转为弧度
            double dlat = dis/r;
            dlat = dlat*180/Math.PI;
            double minlat =latitude-dlat;
            double maxlat = latitude+dlat;
            double minlng = longitude -dlng;
            double maxlng = longitude + dlng;
            tshoplist = merchantManagementMapper.nearbyMerchantRecommend(minlat,maxlat,minlng,maxlng);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("经纬度查询异常，异常信息为{}",e.getMessage(),e);
        }
        if (CollUtil.isNotEmpty(tshoplist)){
            return AjaxResult.success(tshoplist.get(0));
        }else {
            return AjaxResult.success("附近无可提供服务的综合站");
        }
    }


}
